import { ref } from 'vue';
import { defineStore } from 'pinia';
import SsqApi from '@/apis/SsqApi';
import ssqconfig from '@/config/ssq-config';

const { split_index, count_front } = ssqconfig;

/**
 * 数据源管理
 */
export const useSsqDataSourceStore = defineStore('SsqDataSource', () => {

    /**
     * 最后刷新时间
     */
    const refreshTime = ref(0);

    /**
     * 完整数据集
     */
    const dataset = ref([]);

    /**
     * 当前时光机期号
     */
    const activeDrawNum = ref('');

    /**
     * 缓存键名
     */
    const cacheKey = {
        dataSource: 'ssq-data-source',
        refreshTime: 'ssq-refresh-time',
        activeDrawNum: 'ssq-active-draw-num',
    }

    /**
     * 设置数据源
     * @param {Array} rows 
     */
    const setDataSource = (rows) => {
        dataset.value = rows;
        window.localStorage.setItem(cacheKey.dataSource, JSON.stringify(rows));
        console.log('【SsqDataSource数据库】setDataSource ', rows);
    }

    /**
     * 返回数据源
     * @returns {Array} 示例：[{lotteryDrawNum: "25066", lotteryDrawResult: "15 18 27 28 34 03 06", lotteryDrawTime: "2025-06-14"}, ...]
     */
    const getDataSource = () => {
        if (dataset.value.length == 0) {
            dataset.value = JSON.parse(window.localStorage.getItem(cacheKey.dataSource) ?? '[]');
        }
        if (activeDrawNum.value !== '') {
            return dataset.value.filter(row => row.lotteryDrawNum <= activeDrawNum.value)
        }
        return dataset.value;
    }

    /**
     * 设置时光机期号
     * @param {Number} num 
     */
    const setActiveDrawNum = (num) => {
        activeDrawNum.value = num;
        window.localStorage.setItem(cacheKey.activeDrawNum, activeDrawNum.value);
    }

    /**
     * 获取时光机期号
     * @returns {String} 返回期号
     */
    const getActiveDrawNum = () => {
        activeDrawNum.value = window.localStorage.getItem(cacheKey.activeDrawNum) ?? '';
        return activeDrawNum.value || (dataset.value.length > 0 ? dataset.value[0].lotteryDrawNum : '');
    }

    /**
     * 设置刷新时间
     */
    const setRefreshTime = () => {
        refreshTime.value = new Date().getTime();
        window.localStorage.setItem(cacheKey.refreshTime, refreshTime.value);
    }

    const getRefreshTime = (isLocalString = false) => {
        refreshTime.value = parseInt(window.localStorage.getItem(cacheKey.refreshTime) ?? '0');
        if (isLocalString && refreshTime.value > 0) {
            // 返回本地存储的时间字符串
            return new Date(parseInt(refreshTime.value)).toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', weekday: "short", })
                .replaceAll('/', '-').replace('周', ' 周');
        }
        return refreshTime.value;
    }

    /**
     * 检测刷新时间是否过期
     * @param {Number} time 秒
     * @returns Boolean 如果超过指定时间，则返回 true，表示需要刷新数据
     */
    const isExpire = (time = 7200) => {
        return (new Date().getTime() - getRefreshTime(false)) > (time * 1000);
    }

    /**
     * 返回指定号数的列数据
     * @param {Array} data 数据
     * @param {Number} columnIdx 号数列索引（从 0 到 6）
     * @param {Boolean} isLocation 是否是位置数据
     * @returns {Array}
     */
    const getColumnData = (data, columnIdx, isLocation = false) => {
        // const data = getDataSource();
        if (isLocation) {
            let inc = columnIdx < split_index ? 0 : count_front;
            // 返回位置数据，前 5 列是红球，后 2 列是蓝球
            return data.map((row, i) => {
                return [i, parseInt(row.lotteryDrawResult.split(' ')[columnIdx]) + inc];
            });
        }
        return data.map(row => row.lotteryDrawResult.split(' ')[columnIdx]);
    }

    /**
     * 获取每个号码的出现次数统计，包含全部号码统计和每个号数列的统计
     * @param {Array} data 数据源，默认为当前数据源
     * @returns Object {statAll, statColumns}
     */
    const getDrawalStat = (data) => {
        if (!data || data.length === 0) {
            data = getDataSource();
        }
        let statColumns = [{}, {}, {}, {}, {}, {}, {}]; // 1...7
        let statAll = [{}, {}]; // front/back
        let isFront = true; // 是否是前区号码
        data.forEach(row => {
            const nums = row.lotteryDrawResult.split(' ');
            nums.forEach((num, i) => {
                isFront = i < split_index;
                if (!statAll[isFront ? 0 : 1][num]) {
                    statAll[isFront ? 0 : 1][num] = 0;
                }
                statAll[isFront ? 0 : 1][num]++;
                if (!statColumns[i][num]) {
                    statColumns[i][num] = 0;
                }
                statColumns[i][num]++;
            });
        });
        // 排序
        let statAllSorted = [{}, {}], keys = [];
        for (let i = 0; i < 2; i++) {
            keys = Object.keys(statAll[i]);
            keys.sort();
            keys.forEach(key => {
                statAllSorted[i][key] = statAll[i][key];
            });

        }
        statAll = null;
        let statColumnsSorted = [];
        statColumns.forEach(statObj => {
            keys = Object.keys(statObj);
            keys.sort();
            let statSorted = {};
            keys.forEach(key => {
                statSorted[key] = statObj[key];
            });
            statColumnsSorted.push(statSorted);
        });
        statColumns = null;
        return { statAll: statAllSorted, statColumns: statColumnsSorted };
    }

    /**
     * 获取双色球官方远程数据
     * @returns Array 
     * 数据结构
     * list = [ drawing1, drawing2, ...]
     * drawing = {"name":"双色球","code":"2025077","detailsLink":"/c/2025/07/08/621452.shtml","videoLink":"/c/2025/07/08/621457.shtml","date":"2025-07-08(二)",
     *      "week":"二","red":"04,07,08,15,20,21","blue":"15","blue2":"","sales":"354913968","poolmoney":"2412167034",
     *      "content":"河北2注，内蒙古1注，安徽2注，湖南2注，广西1注，四川1注，共9注。","addmoney":"","addmoney2":"","msg":"","z2add":"","m2add":"",
     *      "prizegrades":[{"type":1,"typenum":"9","typemoney":"7448353"},{"type":2,"typenum":"153","typemoney":"180025"},{"type":3,"typenum":"1384","typemoney":"3000"},
     *      {"type":4,"typenum":"66249","typemoney":"200"},{"type":5,"typenum":"1300197","typemoney":"10"},{"type":6,"typenum":"6665636","typemoney":"5"},
     *      {"type":7,"typenum":"","typemoney":""}]}
     */
    const fetchData = () => {
        return new Promise((resolve, reject) => {
            SsqApi.datasource().then(res => {
                console.log('【获取双色球官方远程数据】成功', res);
                resolve((res['data'] ? res.data : res));
            }).catch(err => {
                console.log('【获取双色球官方远程数据】网络错误', err);
                reject(err);
            })
        })
    }

    /**
     * 封装加载数据方法
     * @param {Boolean} isForce 是否强制刷新数据。默认 false。
     * @returns 
     */
    const loadData = (isForce = false) => {
        return new Promise((resolve, reject) => {
            if (isForce || isExpire() || getDataSource().length === 0) {
                console.log('重新加载双色球数据。刷新时间:', getRefreshTime(true));
                fetchData().then(rows => {
                    console.log('加载双色球数据成功');
                    setRefreshTime();
                    setDataSource(rows);
                    resolve(rows);
                }).catch(err => {
                    console.log('加载双色球数据错误', err);
                    reject(err);
                });
            } else {
                console.log('使用双色球缓存数据。刷新时间:', getRefreshTime(true));
            }
        });
    }

    return {
        setRefreshTime,
        getRefreshTime,
        isExpire,
        setDataSource,
        getDataSource,
        setActiveDrawNum,
        getActiveDrawNum,
        fetchData,
        loadData,
        getColumnData,
        getDrawalStat,
    }
})
